<html>
<head><meta charset="utf-8"><title>Compile-time Sets · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Compile-time.20Sets.html">Compile-time Sets</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="208834608"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Compile-time%20Sets/near/208834608" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> XAMPPRocky <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Compile-time.20Sets.html#208834608">(Sep 02 2020 at 14:44)</a>:</h4>
<p>Hey has anyone ever had any luck with trying to hack together sets at compile time on stable? I have a procedural derive macro that essentially associates a unique identifier with a field in a struct and creates a list of those identifiers at compile time. I want to cause a compile error in the generated code if that list contains duplicates. I got this partially working with match (see below), but using a lint to cause the error won't work for derive macros.</p>
<div class="codehilite"><pre><span></span><code><span class="cp">#[derive(PartialEq, Eq)]</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">enum</span> <span class="nc">Foo</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">A</span><span class="p">,</span><span class="w"> </span><span class="n">B</span><span class="p">,</span><span class="w"> </span><span class="n">C</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">const</span><span class="w"> </span><span class="n">A</span>: <span class="nc">Foo</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Foo</span>::<span class="n">A</span><span class="p">;</span><span class="w"></span>
<span class="k">const</span><span class="w"> </span><span class="n">B</span>: <span class="nc">Foo</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Foo</span>::<span class="n">B</span><span class="p">;</span><span class="w"></span>
<span class="k">const</span><span class="w"> </span><span class="n">C</span>: <span class="nc">Foo</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Foo</span>::<span class="n">C</span><span class="p">;</span><span class="w"></span>

<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="n">foo</span>: <span class="nc">Foo</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="cp">#[forbid(unreachable_patterns)]</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">foo</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">A</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="w">        </span><span class="n">A</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="w">        </span><span class="n">B</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="w">        </span><span class="n">C</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="208835717"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Compile-time%20Sets/near/208835717" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Compile-time.20Sets.html#208835717">(Sep 02 2020 at 14:51)</a>:</h4>
<p>If <code>Foo</code> is not Copy, you can move out of a variable with mem::drop or something and that'll only work once</p>



<a name="208835824"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Compile-time%20Sets/near/208835824" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Compile-time.20Sets.html#208835824">(Sep 02 2020 at 14:52)</a>:</h4>
<p>I think with shadowing and type annotations you could build a general solution too, but not sure</p>



<a name="208835879"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Compile-time%20Sets/near/208835879" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Compile-time.20Sets.html#208835879">(Sep 02 2020 at 14:52)</a>:</h4>
<p>Maybe easiest is to declare a struct with those names as fields, and then you'll get an error</p>



<a name="208836514"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Compile-time%20Sets/near/208836514" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Compile-time.20Sets.html#208836514">(Sep 02 2020 at 14:56)</a>:</h4>
<p>You've seen <a href="https://crates.io/crates/phf">https://crates.io/crates/phf</a> I assume?</p>



<a name="208841128"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Compile-time%20Sets/near/208841128" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> XAMPPRocky <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Compile-time.20Sets.html#208841128">(Sep 02 2020 at 15:23)</a>:</h4>
<p><span class="user-mention" data-user-id="116122">@simulacrum</span> Declaring a struct and using the names is quite clever, I'll remember that.  Though in my case it's not enough, I need ensure the value not just the name is unique.</p>
<p><span class="user-mention" data-user-id="116155">@Jake Goulding</span> I hadn't actually since like 2015 when it was really hard to use, I'll try it again though as it looks way easier to use. Thanks!</p>
<p>I also quickly tried to see if I could make a <code>const fn</code> to check but unfortunately it's stopped by <code>PartialEq</code> not be available.</p>
<div class="codehilite"><pre><span></span><code><span class="k">const</span><span class="w"> </span><span class="k">fn</span> <span class="nf">is_unique</span><span class="p">(</span><span class="n">set</span>: <span class="kp">&amp;</span><span class="p">[</span><span class="n">Foo</span><span class="p">])</span><span class="w"> </span>-&gt; <span class="kt">bool</span> <span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="k">while</span><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">set</span><span class="p">.</span><span class="n">len</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">needle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="n">set</span><span class="p">[</span><span class="n">index</span><span class="p">];</span><span class="w"></span>
<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">after</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"></span>
<span class="w">        </span><span class="k">while</span><span class="w"> </span><span class="n">after</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">set</span><span class="p">.</span><span class="n">len</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="k">if</span><span class="w"> </span><span class="n">needle</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="o">&amp;</span><span class="n">set</span><span class="p">[</span><span class="n">after</span><span class="p">]</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">                </span><span class="k">return</span><span class="w"> </span><span class="kc">false</span><span class="w"></span>
<span class="w">            </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">                </span><span class="n">after</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"></span>
<span class="w">            </span><span class="p">}</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>

<span class="w">        </span><span class="n">index</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="kc">true</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="208845839"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Compile-time%20Sets/near/208845839" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> XAMPPRocky <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Compile-time.20Sets.html#208845839">(Sep 02 2020 at 15:50)</a>:</h4>
<p><span class="user-mention" data-user-id="116155">@Jake Goulding</span> Seems like phf won't work as it requires you to use a primitive type and I'm using a struct as my key.</p>



<a name="208939373"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Compile-time%20Sets/near/208939373" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matt1992 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Compile-time.20Sets.html#208939373">(Sep 03 2020 at 09:07)</a>:</h4>
<p><span class="user-mention" data-user-id="219696">@XAMPPRocky</span> <br>
You can compare it for equality like this:<br>
<a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=068f77d25d2b6b81d4094dc0ac8f78d3">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=068f77d25d2b6b81d4094dc0ac8f78d3</a></p>
<div class="codehilite"><pre><span></span><code><span class="cp">#[derive(Copy, Clone, PartialEq, Eq)]</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">enum</span> <span class="nc">Foo</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">A</span><span class="p">,</span><span class="w"> </span><span class="n">B</span><span class="p">,</span><span class="w"> </span><span class="n">C</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">impl</span><span class="w"> </span><span class="n">Foo</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="k">fn</span> <span class="nf">eq</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">other</span>: <span class="kp">&amp;</span><span class="nc">Self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">bool</span> <span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="o">*</span><span class="bp">self</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">u8</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="o">*</span><span class="n">other</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">u8</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>


<p>(you can use any integer type there)</p>



<a name="208939523"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Compile-time%20Sets/near/208939523" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> XAMPPRocky <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Compile-time.20Sets.html#208939523">(Sep 03 2020 at 09:09)</a>:</h4>
<p><span class="user-mention" data-user-id="138909">@matt1992</span> Oh wow, that's perfect, thanks!</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>